#ifndef N1PTR_H_2009_10_05
#define N1PTR_H_2009_10_05

#include "N1Debug.h"

template <class T>
class N1Ptr {
protected:
	T* m_ptr;

public:
	N1Ptr() : m_ptr(NULL) 
	{
	}

	N1Ptr(T* p) : m_ptr(p) 
	{
	}

	N1Ptr(const N1Ptr<T>& p) : m_ptr(p.m_ptr) 
	{
	}

	~N1Ptr() 
	{
	    if(m_ptr)
	    {
	        m_ptr->release();
	    }
	}

	void release() 
	{
	    m_ptr->release();
		m_ptr = NULL;
	}

	T* detach() 
	{
		T* tmp = m_ptr;
		m_ptr = NULL;
		return tmp;
	}

	T* Attach(T* p) 
	{
		release();
		return (T*)(m_ptr = p);
	}

	operator T*() const 
	{
		return (T*)m_ptr;
	}

	T& operator*() const 
	{
		N1Assert(m_ptr!=NULL);
		return *m_ptr;
	}

	T* operator->() const 
	{
		N1Assert(m_ptr!=NULL);
		return m_ptr;
	}

	T* operator=(T* p) 
	{
		release();
		return (T*)(m_ptr = p);
	}

	T* operator=(const N1Ptr<T>& p) {
		release();
		return (T*)(m_ptr = p.m_ptr);
	}

	bool operator!() const 
	{
		return m_ptr==NULL;
	}

	bool operator<(T* p) const 
	{
		return m_ptr<p;
	}

	bool operator==(T* p) const 
	{
		return m_ptr==p;
	}
};

#endif //N1PTR_H_2009_10_05
